﻿#include "ssMsgEngine.h"
#include "../tools/ssTools.h"
//#include <cstdio>

namespace StarSeeker
{

ssMsgEngine::ssMsgEngine()
{
	m_maxMsgCount = 1000000;
	m_msgOffset = 0;
	m_useTimer = false;
}

ssMsgEngine::~ssMsgEngine()
{
	ExitThread();
}

bool ssMsgEngine::PostMsg(ssMsg_s &m)
{
	//if (m_msgList.Size() > m_maxMsgCount)
	//{
	//	return false;
	//}
	SS_MUTEX_LOCK(m_mutex)
		m_msgList[m_msgOffset].PushBack(m);
	SS_MUTEX_UNLOCK(m_mutex)
	return true;
}

bool ssMsgEngine::PostMsg(u32 msgID, u32 subID, ulint param1, ulint param2, ulint param3)
{
	ssMsg_s msg(msgID, subID, param1, param2, param3);
	return PostMsg(msg);
}

void ssMsgEngine::ThreadMemberFunc()
{
	OnThreadRun();
	while (!IsRequestStop())
	{
		if (m_msgList[m_msgOffset].Size()>0)
		{
			BeforeEventLoop();

			ssList<ssMsg_s>* tempList = 0;
			SS_MUTEX_LOCK(m_mutex)
				tempList = m_msgList + m_msgOffset;
				m_msgOffset = (m_msgOffset + 1) % 2;
			SS_MUTEX_UNLOCK(m_mutex)

			u32 now = ssTime::GetTimeNow().u32p;
			ssList<ssMsg_s>::Iterator itr = tempList->Begin();
			while (itr.IsVaild())
			{
				switch (itr.Data()->msgID)
				{
				case SS_THREAD_STOP:
					RequestStop();
					break;
				case SS_THREAD_CLEAR:
					SS_MUTEX_LOCK(m_mutex)
						m_msgList[0].Release();
						m_msgList[1].Release();
					SS_MUTEX_UNLOCK(m_mutex)
					break;
				case SS_TIMER_ONCE:
					if (now > itr.Data()->subID)
					{
						HandleMessage(*itr);
					}
					else
					{
						SS_MUTEX_LOCK(m_mutex)
							m_msgList[m_msgOffset].PushBack(*itr);
						SS_MUTEX_UNLOCK(m_mutex)
					}
					break;
				default:
					HandleMessage(*itr.Data());
					break;
				}
				++itr;
			}
			tempList->Empty();
		}

		if (m_useTimer)
		{
			m_timer.UpdateTime();
		}

		AfterEventLoop();
		ssThreadBase::Sleep(1);
	}
	OnThreadExit();
}

void ssMsgEngine::ExitThread()
{
	if (!IsRequestStop())
	{
		ssMsg_s m;
		m.msgID = SS_THREAD_STOP;
		PostMsg(m);
		ssThreadBase::Sleep(100);
		WaitForExit();
	}
}

void ssMsgEngine::SetMaxMsgCount(u32 ct)
{
	m_maxMsgCount = ct;
}

Byte8_u ssMsgEngine::GetMsgCount()
{
	Byte8_u ret;
	ret.u32p[0] = (u32)m_msgList[0].Size();
	ret.u32p[1] = (u32)m_msgList[1].Size();
	return ret;
}

Byte8_u ssMsgEngine::GetMsgMaxCount()
{
	Byte8_u ret;
	ret.u32p[0] = (u32)m_msgList[0].Total();
	ret.u32p[1] = (u32)m_msgList[1].Total();
	return ret;
}

void ssMsgEngine::OnThreadRun()
{
	m_timer.Init(SS_DIFF_TIMER_TYPE_MS);
	//m_frameTimer.Init(10000, true);
}

}
